package amzn.partner.core;


import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.client.CookieStore;
import org.apache.http.client.ResponseHandler;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import amzn.partner.AmazonPartnerNetActivity;
import android.os.AsyncTask;
import android.util.Log;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;


public class amznclient extends AsyncTask<String,Integer,String> {	
	private String username = "";
	private String password = "";
	private AmazonPartnerNetActivity parentActivity;
	
	private CookieStore cookieStore = new BasicCookieStore();
	private HttpContext localContext = new BasicHttpContext();
	private DefaultHttpClient httpClient = new DefaultHttpClient();
	
	private Calendar ReportFrom = Calendar.getInstance();
	private Calendar ReportTo = Calendar.getInstance();
	
	public amznclient(AmazonPartnerNetActivity activity){
		this.parentActivity = activity;
		this.localContext.setAttribute(ClientContext.COOKIE_STORE, this.cookieStore);
		this.httpClient.setCookieStore(this.cookieStore);
		this.ReportFrom.set(Calendar.DAY_OF_MONTH, 1);
		this.ReportTo.set(this.ReportTo.get(Calendar.YEAR), 
						this.ReportTo.get(Calendar.MONTH), 
						this.ReportTo.getActualMaximum(Calendar.DAY_OF_MONTH));
	}
	
	public void setReportingTimeframe(Calendar reportFrom, Calendar reportTo){
		this.ReportFrom = reportFrom;
		this.ReportTo = reportTo;
	}
	
	public ArrayList<Calendar> getReportingTimeframe(){
		ArrayList<Calendar> result = new ArrayList<Calendar>();
		result.add(this.ReportFrom);
		result.add(this.ReportTo);
		return result;
	}
	
	/* returns the username */
	public String getUsername(){
		return this.username;
	}
	
	/* set the user name for this account */
	public void setUsername(String newUsername){
		this.username = newUsername;
	}
	
	/* set the password for this account */
	public void setPassword(String newPassword){
		this.password = newPassword;
	}
	
	private String wget(String url, String postVars){
		String data = "";
		HttpResponse response = null;
		Header locationHeader = null;
		
		String userAgent = "Mozilla/5.0 (X11; Linux x86_64;"
						+ " rv:7.0) Gecko/20100101 Firefox/7.0";
		
		try {			
			ResponseHandler<String> responseHandler = new BasicResponseHandler();
			
			if(postVars.length() > 0){
				HttpPost postMethod = new HttpPost(url);
				postMethod.setHeader("User-Agent", userAgent);
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
				
				String[] postVarList = postVars.split("&");
				for(int p=0; p<postVarList.length; p++){
					String[] postVarItem = postVarList[p].split("=");
					String varName = postVarItem[0];
					String varValue = "";
					if(postVarItem.length == 2){
						varValue = postVarItem[1];
					}
					nameValuePairs.add(new BasicNameValuePair(varName, varValue));
				}
		        postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
		        this.localContext.setAttribute(ClientContext.COOKIE_STORE, this.cookieStore);
				this.httpClient.setCookieStore(this.cookieStore);
		        response = this.httpClient.execute(postMethod,this.localContext);
		        locationHeader = postMethod.getFirstHeader("Location");
			}else{
				HttpGet getMethod = new HttpGet(url);
				getMethod.setHeader("User-Agent", userAgent);
				this.localContext.setAttribute(ClientContext.COOKIE_STORE, this.cookieStore);
				this.httpClient.setCookieStore(this.cookieStore);
				response = this.httpClient.execute(getMethod,this.localContext);
				locationHeader = getMethod.getFirstHeader("Location");
			}
			
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode == 200) {
				data = responseHandler.handleResponse(response);
			}if (statusCode == 302) {
				data = this.wget(locationHeader.getValue(), "");
			}
			
		} catch (Exception e) {
			data = "";
		}
		
		return data;
	}
	
	/* fetches the report data from amazon */
	protected String fetch(){
		String result = "";
		try{			
			String loginPageHtml = this.wget("https://partnernet.amazon.de/"
	        						+ "gp/associates/login/login.html", "");
	
			// parse the session id out of the raw html
	        // and process the actual login
	        if(loginPageHtml.indexOf("name=\"sessionId\"") > 0){
	        	String sessionId = loginPageHtml.substring(loginPageHtml.indexOf
	        								("name=\"sessionId\"")).substring(24);
	        	sessionId = sessionId.substring(0,sessionId.indexOf("\""));
	        	String loggedInPageHtml = "";
	        	
	        	String urlParameters = "__mk_de_DE=%C3%85M%C3%85Z%C3%95%C3%91&action=sign-in&mode=1" 
			        				+ "&path=/gp/associates/login/login.html"
			        				+ "&useRedirectOnSuccess=0&query=&pageAction=/gp/associates/login/login.html"
			        				+ "&disableCorpSignUp=&protocol=https&referer=flex&sessionId=" 
			        				+ sessionId + "&email=" + this.username
			        				+ "&password=" + this.password; 
	        	
	        	// process the actual login
	        	loggedInPageHtml = this.wget("https://partnernet.amazon.de/"
										+ "gp/flex/sign-in/select.html", urlParameters);
			    
				// on success it redirects
				if(loggedInPageHtml.indexOf("Angemeldet als")>0){		
					String reportUrl = "https://partnernet.amazon.de/gp/associates/network/reports/report.html"
									+ "?__mk_de_DE=%C3%85M%C3%85Z%C3%95%C3%91&tag=&reportType=earningsReport"
									+ "&program=all&preSelectedPeriod=yesterday&periodType=exact"
									+ "&startDay=" + Integer.toString(this.ReportFrom.get(Calendar.DAY_OF_MONTH))
									+ "&startMonth=" + Integer.toString(this.ReportFrom.get(Calendar.MONTH))
									+ "&startYear=" + Integer.toString(this.ReportFrom.get(Calendar.YEAR))
									+ "&endDay=" + Integer.toString(this.ReportTo.get(Calendar.DAY_OF_MONTH))
									+ "&endMonth=" + Integer.toString(this.ReportTo.get(Calendar.MONTH))
									+ "&endYear=" + Integer.toString(this.ReportTo.get(Calendar.YEAR))
									+ "&submit.download_XML.x=102&submit.download_XML.y=4";
					String reportXml = this.wget(reportUrl, "");
					if(reportXml.indexOf("<AMZNShipmentTotals>") > 0){
						result = reportXml;
					}else{
						result = "DATA_DOWNLOAD_FAILED";
					}
				}else{
					result = "LOGIN_FAILED";
				}
			}else{ 
				result = "LOGIN_FAILED";
			}
	    }catch(Exception ex){
			Log.e("APN", ex.getMessage());
		}
		
		return result;		
	}

	@Override
	protected String doInBackground(String... params) {
		String result;
		try {
			result = this.fetch();
		} catch (Exception e) {
			Log.e("APN", e.getMessage());
			result = null;
		}

		return result;
	}
	
	@Override
	protected void onPostExecute(String result) {
		this.parentActivity.updateDataReady(result);
	}
	
}
